package mail;

import java.io.File;
import java.util.ArrayList;
import java.util.Properties;
import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.*;
import javax.mail.internet.*;

public class Email {
    private static final String smtpHost = "smtp.sina.com";
    private static final String pop3Host = "pop3.sina.com";
    private static final String homeAddress = "fgksgf@sina.com";
    private static final String password = "jhx79731559";

    private static final String attachmentPath = "doc/TestAttachment.txt";
    private static final String attachmentName = "TestAttachment.txt";
    private static final String imageName = "doc/test.jpg";
    private static final String textContent = "<p>Do you like me ?<br/>"
            + "/* Reply to me in a simple English sentence no more than six words, please."
            + "Thank you for cooperation. */</p><br/>"
            + "<img src=\"cid:test_jpg\"></img>";

    // Store all mails in the inbox.
    private static ArrayList<Mail> mails = new ArrayList<>();

    /**
     * Creates an attachment based on the file path passed in and return it.
     */
    private static MimeBodyPart setAttachment(String path, String fileName) throws Exception {
        MimeBodyPart attachPart = new MimeBodyPart();

        // Specify an attachment for the component
        attachPart.attachFile(new File(path));

        // Specifies the name of the attachment file
        attachPart.setFileName(MimeUtility.encodeText(fileName));

        return attachPart;
    }

    /**
     * Set the message body and picture.
     */
    private static MimeBodyPart setContent(String text, String fileName) throws Exception {
        // Used to save the final body part.
        MimeBodyPart contentBody = new MimeBodyPart();

        // Used to combine text and pictures.
        MimeMultipart contentMulti = new MimeMultipart("related");

        // Set the text section.
        MimeBodyPart textPart = new MimeBodyPart();
        textPart.setContent(text, "text/html;charset=utf-8");
        contentMulti.addBodyPart(textPart);

        // Set the picture section.
        MimeBodyPart jpgPart = new MimeBodyPart();
        FileDataSource fds = new FileDataSource(fileName);
        jpgPart.setDataHandler(new DataHandler(fds));
        jpgPart.setContentID("test_jpg");
        contentMulti.addBodyPart(jpgPart);

        contentBody.setContent(contentMulti);
        return contentBody;
    }

    private static MimeMessage createMessage(Session session) throws Exception {
        MimeMessage message = new MimeMessage(session);
        message.setFrom(new InternetAddress(homeAddress));
        message.setSubject("Java Homework Test");

        MimeMultipart allPart = new MimeMultipart("mixed");
        MimeBodyPart attachment = Email.setAttachment(attachmentPath, attachmentName);
        MimeBodyPart content = Email.setContent(textContent, imageName);

        allPart.addBodyPart(attachment);
        allPart.addBodyPart(content);
        message.setContent(allPart);
        return message;
    }

    public static Session getSendSession() {
        Properties props = System.getProperties();
        props.put("mail.smtp.host", smtpHost);
        props.put("mail.smtp.auth", "true");
        Session session = Session.getDefaultInstance(props, new Authenticator() {
            @Override
            public PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(homeAddress, password);
            }
        });
        return session;
    }

    /**
     * Send a email with the attachment to the target address.
     *
     * @param targetAddress
     */
    public static void sendMail(String targetAddress, Session session) {
        try {
            MimeMessage message = createMessage(session);
            message.addRecipient(Message.RecipientType.TO,
                    new InternetAddress(targetAddress));
            Transport.send(message);
            System.out.println("Send to " + targetAddress + " successfully !");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * Acquire mails from the inbox and store them.
     */
    public static boolean receiveMail() {
        boolean flag = false;
        Properties props = System.getProperties();
        Session session = Session.getInstance(props, null);
        URLName url = new URLName("pop3", pop3Host, 110,
                null, homeAddress, password);

        try {
            Store store = session.getStore(url);
            store.connect();

            // Attain the inbox folder's contents
            Folder folder = store.getFolder("INBOX");

            // Open the folder in read-only way
            folder.open(Folder.READ_ONLY);
            Message[] messages = folder.getMessages();

            /**
             * When the number of messages in the Inbox is greater than the number of
             * messages that have been received, add the new mails to ArrayList.
             */
            if (messages.length > mails.size()) {
                flag = true;
                for (int i = mails.size(); i < messages.length; ++i) {
                    Mail mail = new Mail((MimeMessage) messages[i]);
                    mails.add(mail);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return flag;
    }

    /**
     * Display a mail's subject, from, date and content.
     *
     * @param i The index of the mail to be displayed.
     */
    public static void showMail(int i, boolean choice) throws Exception {
        System.out.println("============= Message " + (i + 1) + " =============");
        mails.get(i).display(choice);
        System.out.println();
    }

    public static int getMailsCount() {
        return mails.size();
    }
}
